/**
 * Cookie 配置选项
 */
export interface CookieOptions {
  /** 过期时间（Date 对象或天数） */
  expires?: Date | number
  /** 路径（默认 '/'） */
  path?: string
  /** 域名（默认当前域名） */
  domain?: string
  /** 是否仅通过 HTTPS 传输（默认 false） */
  secure?: boolean
  /** SameSite 策略（默认 'Lax'） */
  sameSite?: 'Strict' | 'Lax' | 'None'
}

export default class Cookie {
  /**
   * 设置 Cookie
   * @param name Cookie 名称
   * @param value Cookie 值
   * @param options 配置选项
   */
  static set(name: string, value: string, options: CookieOptions = {}): void {
    if (!name)
      return

    let cookieStr = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`

    // 处理过期时间
    if (options.expires) {
      const expires
        = options.expires instanceof Date
          ? options.expires.toUTCString()
          : new Date(
            Date.now() + options.expires * 24 * 60 * 60 * 1000,
          ).toUTCString()
      cookieStr += `; expires=${expires}`
    }

    // 处理其他选项
    if (options.path)
      cookieStr += `; path=${options.path}`
    if (options.domain)
      cookieStr += `; domain=${options.domain}`
    if (options.secure)
      cookieStr += '; secure'
    if (options.sameSite)
      cookieStr += `; SameSite=${options.sameSite}`

    document.cookie = cookieStr
  }

  /**
   * 获取 Cookie
   * @param name Cookie 名称
   * @returns Cookie 值（未找到返回 null）
   */
  static get(name: string): string | null {
    if (!name)
      return null

    const cookies = document.cookie.split(';')
    for (const cookie of cookies) {
      const [key, value] = cookie.split('=').map(item => item.trim())
      if (decodeURIComponent(key) === name) {
        return decodeURIComponent(value)
      }
    }
    return null
  }

  /**
   * 删除单个 Cookie
   * @param name Cookie 名称
   * @param options 配置选项（需与设置时一致）
   */
  static remove(name: string, options: CookieOptions = {}): void {
    if (!name)
      return

    // 设置过期时间为过去，并确保 path 和 domain 匹配
    this.set(name, '', {
      ...options,
      expires: new Date(0),
    })
  }

  /**
   * 清除所有 Cookie（当前域名下）
   * @param options 配置选项（可选）
   */
  static clear(options: Pick<CookieOptions, 'path' | 'domain'> = {}): void {
    const cookies = document.cookie.split(';')

    for (const cookie of cookies) {
      const [name] = cookie.split('=').map(item => item.trim())
      const decodedName = decodeURIComponent(name)

      // 尝试解析原始 path 和 domain（如果未提供）
      const originalCookie = document.cookie.split(`${name}=`)[1] || ''
      const path
        = options.path || originalCookie.split('; path=')[1]?.split(';')[0] || '/'
      const domain
        = options.domain || originalCookie.split('; domain=')[1]?.split(';')[0]

      // 删除 Cookie
      this.remove(decodedName, { path, domain })
    }
  }
}
